﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxCallback;
using System.Configuration;
using System.Collections.Specialized;
using System.Web.Security;
using DevExpress.Web.ASPxGridView;

namespace TireService.Website
{
    public partial class Bestilling : System.Web.UI.Page
    {
        // NOTE: Not a good solution - hardcoded price values for tireset pickup
        private decimal _tirepickupprice_beforevat = 200;
        private decimal _tirepickupprice_aftervat = 250;

        protected void Page_Load(object sender, EventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            if (Page.IsPostBack != true)
            {
                // Reset order and car list
                //Session["CustomerOrder"] = null;
                //Session["CarList"] = null;

                // Test variables
                //Session["CustomerAddress"] = "Mylius Erichsens Vej 50";
                //Session["CustomerZipCode"] = "7400";
                //Session["CustomerCity"] = "Herning";

                // Bind subscription data to radiobutton list
                rblSubscription.DataSource = db.GetSubscription().Where(p => p.InActive == false & p.Business == false).OrderBy(p => p.OrderingSequence);
                rblSubscription.TextField = "Description";
                rblSubscription.ValueField = "SubscriptionId";
                rblSubscription.DataBind();

                // Get data for dropdownlist
                ddlCountry.DataSource = db.GetCountries();
                ddlCountry.ValueField = "CountryId";
                ddlCountry.TextField = "CountryName";
                ddlCountry.DataBind();

                // Bind orderlist and car list based on session
                if (Session["CustomerOrder"] != null)
                {
                    gvSelectedProducts.DataSource = (List<OrderData>)Session["CustomerOrder"];
                    gvSelectedProducts.DataBind();
                }
                if (Session["CarList"] != null)
                {
                    gvCars.DataSource = (List<CarData>)Session["CarList"];
                    gvCars.DataBind();
                }

                if (Request.QueryString["Id"] != null)
                {
                    try
                    {
                        rblSubscription.Value = Request.QueryString["Id"];

                        // Register subscription selection on client
                        Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScriptSubscriptionSelectionChanged", "SubscriptionSelectionChanged();", true);
                    }
                    catch (Exception)
                    {
                        // Nothing
                    }
                }

                if (Request.QueryString["Voucher"] != null)
                {
                    txtVoucher.Text = Convert.ToString(Request.QueryString["Voucher"]);

                    // Register coupon code click on client
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScriptLoadVoucher", "LoadVoucher();", true);
                }
            }
        }

        /// <summary>
        /// Gridview function that change field data for unbound fields
        /// </summary>
        protected void gvSelectedProducts_CustomUnboundColumnData(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewColumnDataEventArgs e)
        {
            //// Format UnBoundColumn Type: UnitPriceValue
            //if (e.Column.FieldName == "UnitPriceValue")
            //{
            //    // Get unitprice
            //    decimal unitprice = Convert.ToDecimal(e.GetListSourceFieldValue("UnitPrice"));

            //    // Change field value
            //    e.Value = unitprice.ToString() + " DKK";
            //}

            //// Format UnBoundColumn Type: TotalPriceValue
            //if (e.Column.FieldName == "TotalPriceValue")
            //{
            //    // Get totalprice
            //    decimal totalprice = Convert.ToDecimal(e.GetListSourceFieldValue("TotalPrice"));

            //    // Change field value
            //    e.Value = totalprice.ToString() + " DKK";
            //}
        }

        /// <summary>
        /// Callback function that returns info about subscription
        /// </summary>
        protected void callBackSubscriptionSelected_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                // Initiate database connection
                TireServiceDB db = new TireServiceDB();

                Subscription subscription = db.GetSubscription(Convert.ToInt32(e.Parameter));

                if (subscription == null)
                {
                    throw new ArgumentException("Produkt blev ikke fundet - prøv venligst igen eller kontakt vores kundesupport");
                }

                // Create return values (0: Description, 1: Price, 3: HTML description)
                string values = subscription.Description + "|" + string.Format("{0:N}", subscription.StandardPrice) + " DKK incl. moms" + "|" + subscription.DescriptionHTML;

                // Return values to client
                e.Result = values;
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function that updates customer order
        /// </summary>
        protected void callBackAddSubscription_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                // Initiate database connection
                TireServiceDB db = new TireServiceDB();

                // Get values (0: SubscriptionId, 1: Quantity to add)
                string[] param = e.Parameter.Split('|');

                int SubscriptionId = Convert.ToInt32(param[0]);
                decimal Quantity = Convert.ToDecimal(param[1]);
                decimal CurrentQuantity = 0;

                List<OrderData> customerorders = new List<OrderData>();

                Subscription subscription = db.GetSubscription(SubscriptionId);

                if (subscription == null)
	            {
		            throw new ArgumentException("Produkt ikke fundet - venligst kontakt vores kundesupport");
	            }

                if (Session["CustomerOrder"] != null)
                {
                    // Get existing order from session
                    customerorders = (List<OrderData>)Session["CustomerOrder"];

                    // Check if subscription already in order
                    OrderData currentorder = customerorders.SingleOrDefault(p => p.SubscriptionId == SubscriptionId);

                    if (currentorder == null)
                    {
                        // Current order does not contain this subscription - do nothing
                    }
                    else
                    {
                        // Update current quantity variables based on current orderline
                        CurrentQuantity = currentorder.Quantity;

                        // Remove orderline from session
                        customerorders.Remove(currentorder);
                    }
                }
                
                // Create orderline
                OrderData customerorder = new OrderData();
                customerorder.SubscriptionId = subscription.SubscriptionId;
                customerorder.Description = subscription.Description;
                customerorder.ProductNumber = subscription.EconomicProductNumber;
                customerorder.Quantity = CurrentQuantity + Quantity;
                customerorder.UnitPrice = subscription.StandardPrice;
                customerorder.OneTimeUnitPrice = subscription.StandardPrice;
                customerorder.TotalPrice = (customerorder.OneTimeUnitPrice * (CurrentQuantity + Quantity));

                customerorders.Add(customerorder);

                // Update session with updated order
                Session["CustomerOrder"] = customerorders;
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        protected void gvSelectedProducts_RowDeleting(object sender, DevExpress.Web.Data.ASPxDataDeletingEventArgs e)
        {
            if (Session["CustomerOrder"] != null)
            {
                // Get order / subscription to remove
                int SubscriptionId = Convert.ToInt32(e.Keys[0]);

                // Get current selected ordres
                List<OrderData> customerorders = (List<OrderData>)Session["CustomerOrder"];

                // Find order for removal
                OrderData order = customerorders.SingleOrDefault(p => p.SubscriptionId == SubscriptionId);

                if (order != null)
                {
                    // Remove order
                    customerorders.Remove(order);                    

                    // Save session
                    Session["CustomerOrder"] = customerorders;

                    // Check if any cars has been added to orders being removed
                    if (Session["CarList"] != null)
                    {
                        List<CarData> cars = (List<CarData>)Session["CarList"];

                        foreach (CarData car in cars)
                        {
                            if (car.SubscriptionId == SubscriptionId)
                            {
                                // Remove car
                                cars.Remove(car);
                            }
                        }

                        // Save session
                        Session["CarList"] = cars;
                    }
                }
            }

            e.Cancel = true;

            // Refresh gridview
            if (Session["CustomerOrder"] != null)
            {
                gvSelectedProducts.DataSource = (List<OrderData>)Session["CustomerOrder"];
                gvSelectedProducts.DataBind();
            }
        }


        /// <summary>
        /// Callback function that checks if customer address was pre-filled in booking page
        /// </summary>
        protected void callBackCustomerAddressPrefilled_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                if (Session["CustomerAddress"] != null & Session["CustomerZipCode"] != null & Session["CustomerCity"] != null)
                {
                    e.Result = Session["CustomerAddress"].ToString() + "|" + Session["CustomerZipCode"].ToString() + "|" + Session["CustomerCity"].ToString();
                }
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Postback function that updates customer order list based on session variable
        /// </summary>
        protected void gvSelectedProducts_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            if (Session["CustomerOrder"] != null)
	        {
                gvSelectedProducts.DataSource = (List<OrderData>)Session["CustomerOrder"];
                gvSelectedProducts.DataBind();
	        }
        }

        /// <summary>
        /// Postback function that updates car list based on session variable
        /// </summary>
        protected void gvCars_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            if (Session["CarList"] != null)
	        {
                gvCars.DataSource = (List<CarData>)Session["CarList"];
                gvCars.DataBind();
	        }
        }

        /// <summary>
        /// Postback function that prepare form for entering car information
        /// </summary>
        protected void callbackCarInfoPanel_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            try
            {
                if (Session["CustomerOrder"] != null)
                {
                    List<OrderData> customerorders = (List<OrderData>)Session["CustomerOrder"];

                    // Calculate number of cars and needed usercontrols to be loaded
                    int carcount = Convert.ToInt32(customerorders.Where(p => p.SubscriptionId != null).Sum(d => d.Quantity));

                    // Set carcount value in hidden field
                    hfCarCount["CarCount"] = carcount.ToString();

                    // Check if cars already typed in for orders
                    if (Session["CarList"] != null & e.Parameter == string.Empty)
                    {
                        // Only hide if more than one car on order
                        if (carcount > 1)
                        {
                            // Hide header for more cars
                            lblPrimaryAddressTimeInterval.Visible = false;
                            lblCarToAdd.Visible = false;

                            // Hide add car usercontrol
                            ucAddCarData1.Visible = false;
                        }
                        else
                        {
                            // Load add car usercontrol and car for re-edit

                            // Get car
                            List<CarData> cardata = (List<CarData>)Session["CarList"];
                            CarData car = cardata.First();

                            // Set properties in usercontrol
                            ucAddCarData1.CarNumber = 1;
                            ucAddCarData1.SubscriptionId = Convert.ToInt32(customerorders.Where(p => p.SubscriptionId != null).ElementAt((ucAddCarData1.CarNumber - 1)).SubscriptionId);
                            ucAddCarData1.PrimaryAddress = txtAddress.Text + "|" + txtZipCode.Text + "|" + txtCity.Text;
                            ucAddCarData1.SecondaryAddress = txtSecondaryAddress.Text + "|" + txtSecondaryZipCode.Text + "|" + txtSecondaryCity.Text;

                            ucAddCarData1.Reload(carcount);
                            ucAddCarData1.LoadCar(car);
                        }
                    }
                    else
                    {
                        if (e.Parameter == "")
                        {
                            // First time control is loaded

                            // Set primary address checkbox
                            rbPrimaryAddressTimeInterval.Items.Clear();
                            DevExpress.Web.ASPxEditors.ListEditItem itemPrimary = new DevExpress.Web.ASPxEditors.ListEditItem();
                            itemPrimary.Value = "true";
                            itemPrimary.Text = txtAddress.Text + ", " + txtZipCode.Text + " " + txtCity.Text;
                            rbPrimaryAddressTimeInterval.Items.Add(itemPrimary);

                            DevExpress.Web.ASPxEditors.ListEditItem itemSecondary = new DevExpress.Web.ASPxEditors.ListEditItem();
                            itemSecondary.Value = "false";
                            itemSecondary.Text = txtSecondaryAddress.Text + ", " + txtSecondaryZipCode.Text + " " + txtSecondaryCity.Text;
                            rbPrimaryAddressTimeInterval.Items.Add(itemSecondary);


                            if (carcount > 1)
                            {
                                // Load header for more cars needed
                                lblCarToAdd.Text = "Indtast data for bil 1 af " + carcount.ToString();
                            }

                            // Set properties in usercontrol
                            ucAddCarData1.CarNumber = 1;
                            ucAddCarData1.SubscriptionId = Convert.ToInt32(customerorders.Where(p => p.SubscriptionId != null).ElementAt((ucAddCarData1.CarNumber - 1)).SubscriptionId);
                            ucAddCarData1.PrimaryAddress = txtAddress.Text + "|" + txtZipCode.Text + "|" + txtCity.Text;
                            ucAddCarData1.SecondaryAddress = txtSecondaryAddress.Text + "|" + txtSecondaryZipCode.Text + "|" + txtSecondaryCity.Text;

                            ucAddCarData1.Reload(carcount);
                        }
                        else
                        {
                            // Get client input
                            string[] values = e.Parameter.Split('|');

                            // Check if editing of existing car is selected
                            if (values.Count() > 1)
                            {
                                if (values[0].ToString() == "Edit")
                                {
                                    // Get carnumber
                                    int CarNumber = Convert.ToInt32(values[1]);

                                    List<CarData> cardata = (List<CarData>)Session["CarList"];
                                    CarData car = cardata.SingleOrDefault(p => p.CarNumber == CarNumber);

                                    // Set properties in usercontrol
                                    ucAddCarData1.CarNumber = CarNumber;
                                    ucAddCarData1.SubscriptionId = car.SubscriptionId; // Convert.ToInt32(customerorders.Where(p => p.SubscriptionId != null).ElementAt((ucAddCarData1.CarNumber - 1)).SubscriptionId);
                                    ucAddCarData1.PrimaryAddress = txtAddress.Text + "|" + txtZipCode.Text + "|" + txtCity.Text;
                                    ucAddCarData1.SecondaryAddress = txtSecondaryAddress.Text + "|" + txtSecondaryZipCode.Text + "|" + txtSecondaryCity.Text;

                                    ucAddCarData1.Reload(carcount);
                                    ucAddCarData1.LoadCar(car);
                                }
                            }
                            else
                            {
                                // Saving of car has just happend - take next car
                                int NextCarNumber = Convert.ToInt32(e.Parameter) + 1;

                                // Check if more cars are in the list
                                if ((carcount - NextCarNumber) >= 0)
                                {
                                    // Get subscription id
                                    int order_quantityno = 0;
                                    int subscriptionid = 0;
                                    foreach (OrderData order in customerorders.Where(p => p.SubscriptionId != null))
                                    {
                                        int previousorder_quantityno = order_quantityno;
                                        order_quantityno += Convert.ToInt32(order.Quantity);
                                        if (previousorder_quantityno < NextCarNumber & NextCarNumber <= order_quantityno)
                                        {
                                            subscriptionid = Convert.ToInt32(order.SubscriptionId);
                                        }
                                    }

                                    ucAddCarData1.CarNumber = NextCarNumber;
                                    ucAddCarData1.SubscriptionId = subscriptionid; // Convert.ToInt32(customerorders.Where(p => p.SubscriptionId != null).ElementAt((NextCarNumber - 1)).SubscriptionId);
                                    ucAddCarData1.PrimaryAddress = txtAddress.Text + "|" + txtZipCode.Text + "|" + txtCity.Text;
                                    ucAddCarData1.SecondaryAddress = txtSecondaryAddress.Text + "|" + txtSecondaryZipCode.Text + "|" + txtSecondaryCity.Text;

                                    ucAddCarData1.Reload(carcount);

                                    // Update header
                                    lblCarToAdd.Text = "Indtast data for bil " + NextCarNumber.ToString() + " af " + carcount.ToString();
                                }
                                else
                                {
                                    // Hide header for more cars
                                    lblCarToAdd.Visible = false;

                                    // Hide add car usercontrol
                                    ucAddCarData1.Visible = false;
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Der er ikke lagt nogle produkter i bestillingen - venligst start din bestilling forfra eller kontakt vores kundesupport.");
                }
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function load confirm form for customer/user
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void callbackStep4_CustomerConfirmPanel_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            try
            {
                // Check if voucher/quotation without subscription has been selected
                bool NoSubscriptionOrder = false;

                if (e.Parameter != string.Empty)
                {
                    int quotation = Convert.ToInt32(e.Parameter);

                    if (quotation == 1)
                    {
                        // Order based on quotation, but without subscriptions has been selected
                        NoSubscriptionOrder = true;
                    }
                }

                // Show data entered by customer
                if (Session["CustomerOrder"] != null)
                {
                    TireServiceDB db = new TireServiceDB();
                    gvConfirmProducts.DataSource = (List<OrderData>)Session["CustomerOrder"];
                    gvConfirmProducts.DataBind();
                }
                else
                {
                    throw new ArgumentException("Ingen produkter valgt - venligst prøv igen eller kontakt vores kundesupport.");
                }

                if (Session["CarList"] != null)
                {
                    TireServiceDB db = new TireServiceDB();

                    List<CarData> cars = (List<CarData>)Session["CarList"];

                    gvConfirmCars.DataSource = cars;
                    gvConfirmCars.DataBind();

                    // Check if tireset should be picked up - show full ordre total
                    bool ShowCostTirePickup = false;
                    decimal TotalTirePickupPrice = 0;
                    decimal TotalOrderPrice = 0;
                    foreach (CarData car in cars)
                    {
                        if (car.OtherTireset == 1)
                        {
                            TotalTirePickupPrice += _tirepickupprice_aftervat;
                            ShowCostTirePickup = true;
                        }
                    }
                    // Calculate total order price
                    TotalOrderPrice = TotalTirePickupPrice + Convert.ToDecimal(gvConfirmProducts.GetTotalSummaryValue(gvConfirmProducts.TotalSummary["TotalPrice"]));

                    lblTirePickupPrice.Text = TotalTirePickupPrice.ToString() + " DKK";
                    lblTotalOrderPrice.Text = TotalOrderPrice.ToString() + " DKK";

                    // Show full order price if needed
                    pShowCostTirePickup.Visible = ShowCostTirePickup;

                    lCustomerData.Text = "Navn: " + txtName.Text + "<br>Primær adresse: " + txtAddress.Text + ", " + txtZipCode.Text + " " + txtCity.Text + "<br>Sekundær adresse: " + txtSecondaryAddress.Text + ", " + txtSecondaryZipCode.Text + " " + txtSecondaryCity.Text + "<br>Telefon1: " + txtPhone1.Text + "<br>Telefon2: " + txtPhone2.Text + "<br>Email: " + txtEmail.Text + "<br>";
                }
                else
                {
                    if (NoSubscriptionOrder)
                    {
                        
                    }
                    else
                    {
                        throw new ArgumentException("Ingen biler påført valgte produkter - venligst prøv igen eller kontakt vores kundesupport.");
                    }
                    
                }

                // Show/hide subscription signup confirmation information - depending on if order contains subscription products or not
                pSubscriptionSignUpInformation.Visible = !NoSubscriptionOrder;

                // Set value in hidden field
                hfNoSubscriptionOrder["NoSubscriptionOrder"] = NoSubscriptionOrder.ToString();
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function that saves customer data and finalise payment
        /// </summary>
        protected void callBackFinaliseOrder_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                // Get values from client
                // 0: Name
                // 1: Address
                // 2: ZipCode
                // 3: City
                // 4: Country
                // 5: UsePrimaryAddress
                // 6: SecondaryAddress
                // 7: SecondaryZipCode
                // 8: SecondaryCity
                // 9: Phone1
                // 10: Phone1Type
                // 11: Phone2
                // 12: Phone2Type
                // 13: Email
                // 14: Reference
                // 15: PaymentMethod (1: Creditcard, 2: Banktransfer)                
                // 16: On primary address in primetime
                // 17: Reference (how has the customer heard about us?)
                
                //// 1: Creditcard number
                //// 2: Expire month
                //// 3: Expire year
                //// 4: Securitycode
                string[] param = e.Parameter.Split('|');

                // Define system userid (Used for logging)
                Guid SystemUserId = new Guid(ConfigurationManager.AppSettings["SystemUserId"].ToString()); // System ID - Jannik79

                // Initiate datalayer
                TireServiceDB db = new TireServiceDB();
                
                // Create customer
                Customer customer = new Customer();

                // Declare values
                int customerid = 0;
                bool parentcompany = false;
                int? parentcustomerid = null;
                bool parentpayinvoice = false;
                string companyname = null;
                string companynumber = null;
                string name = param[0];
                string address = param[1];
                string zipcode = param[2];
                string city = param[3];
                int countryid = Convert.ToInt32(param[4]);
                bool useprimaryaddress = Convert.ToBoolean(param[5]); // NOTE: Not for any use - just to indicate primary and secondary is the same
                string secondaryaddress = param[6];
                string secondaryzipcode = param[7];
                string secondarycity = param[8];
                string phone1 = param[9];
                int phone1type = Convert.ToInt32(param[10]);
                int? phone2type = null;
                string phone2 = param[11];
                if (phone2 != string.Empty)
                {
                    phone2type = Convert.ToInt32(param[12]);
                }
                string email = param[13];
                int customerreference = Convert.ToInt32(param[14]);
                int paymentmethod = Convert.ToInt32(param[15]);
                bool onprimaryaddress = Convert.ToBoolean(param[16]);
                int referencesource = Convert.ToInt32(param[17]);


                if (ddlPhone2Type.SelectedItem != null)
                {
                    phone2type = Convert.ToInt32(ddlPhone2Type.SelectedItem.Value);
                }

                CustomerBLL customerBLL = new CustomerBLL();
                customerBLL.UpdateCustomer(
                                            db,
                                            customer,
                                            customerid,
                                            parentcompany,
                                            parentcustomerid,
                                            parentpayinvoice,
                                            false,
                                            companyname,
                                            companynumber,
                                            name,
                                            address,
                                            zipcode,
                                            city,
                                            countryid,
                                            secondaryaddress,
                                            secondaryzipcode,
                                            secondarycity,
                                            phone1,
                                            phone1type,
                                            phone2,
                                            phone2type,
                                            email,
                                            onprimaryaddress,
                                            true,
                                            false,
                                            false,
                                            true
                                        );

                // Initiate customer subscription business logic
                CustomerSubscriptionBLL customersubscriptionBLL = new CustomerSubscriptionBLL();

                // Instantiate task business logic layer
                TaskBLL taskBLL = new TaskBLL();

                // Initiate E-conomic interface
                EconomicInterface ecoInterface = new EconomicInterface();

                // Instantiate tireset and container business logic
                TireSetBLL tiresetBLL = new TireSetBLL();
                ContainerCargoRoomBLL containerBLL = new ContainerCargoRoomBLL();

                // Instantiate tiresetlog business logic
                TireSetLogBLL tiresetlogBLL = new TireSetLogBLL();

                // For each subscription, create and relate to customer
                List<OrderData> customerorders = new List<OrderData>();
                List<CarData> cardata = new List<CarData>();

                // Create orderline for invoicing
                List<EconomicInterface.EcoOrderLine> orderlines = new List<EconomicInterface.EcoOrderLine>();

                if (Session["CustomerOrder"] != null | Session["CarList"] != null)
                {
                    // Get existing orders and data on cars from session
                    customerorders = (List<OrderData>)Session["CustomerOrder"];
                    cardata = (List<CarData>)Session["CarList"];

                    // Lists made for creating invoice after submitted to database
                    List<CustomerSubscription> created_customersubscriptions = new List<CustomerSubscription>();
                    List<Car> created_cars = new List<Car>();

                    // Create propertie for handling if onetime price is given
                    bool OneTimePrice = false;

                    foreach (OrderData customerorder in customerorders.Where(p => p.SubscriptionId != null))
                    {
                        // Create subscription, car, tireset for each subscription
                        
                        // Get subscription 
                        Subscription subscription = db.GetSubscription(Convert.ToInt32(customerorder.SubscriptionId));

                        // Calculate subscription renew date
                        // Renewal dates: 01/03 and 01/09
                        //DateTime LastRenewalDate = Convert.ToDateTime(DateTime.Now);
                        DateTime LastRenewalDate = customersubscriptionBLL.CalculateLastRenewalDate(Convert.ToDateTime(DateTime.Now));
                        DateTime NextRenewalDate = customersubscriptionBLL.CalculateNextRenewalDate(LastRenewalDate, subscription);
                        decimal Price = customerorder.UnitPrice;
                        if (customerorder.UnitPrice != customerorder.OneTimeUnitPrice)
                        {
                            OneTimePrice = true;
                            Price = customerorder.OneTimeUnitPrice;
                        }

                        bool BalancingIncluded = subscription.BalancingIncluded;

                        foreach (CarData carinfo in cardata.Where(p => p.SubscriptionId == customerorder.SubscriptionId))
                        {
                            // Create customersubscription
                            CustomerSubscription customersubscription = new CustomerSubscription();
                            customersubscriptionBLL.UpdateCustomerSubscription(db, customersubscription, customer, 0, subscription.SubscriptionId, LastRenewalDate, NextRenewalDate, false, BalancingIncluded, Price, SystemUserId, true, "Bestilling af abonnement og bil");

                            // Create new car
                            Car car = new Car();
                            car.RegistrationNumber = carinfo.RegistrationNumber;
                            car.CarBrandId = carinfo.CarBrandId;
                            car.Model = carinfo.Model;
                            car.EngineSize = carinfo.EngineSize;
                            car.FuelType = carinfo.FuelType;
                            car.Year = carinfo.Year;
                            car.Color = carinfo.Color;
                            car.CarStatusId = (int)Shared.CarStatus.NeedsTireChanged;
                            //car.CarStatusId = (int)Shared.CarStatus.AwaitsTireChangePlanning; 

                            // Add relationships to car
                            customer.Cars.Add(car);
                            customersubscription.Cars.Add(car);

                            db.AddCar(car);                               

                            // Placeholder for adding new tires to new car
                            TireSet tireset1 = new TireSet();
                            TireSet tireset2 = new TireSet();

                            // Prepare tasks
                            Task servicetask = new Task();
                            Task pickuptask = new Task();

                            int OtherTireSetAction = carinfo.OtherTireset; // 0: We will get tires on first service, 1: Pickup tires, 2: We have the tires

                            // Add tiresets for new car

                            // Determine what tires are on the car
                            int tireset1status, tireset2status;
                            int? tireset1container, tireset2container;
                            bool tireset1lockingbolt, tireset2lockingbolt;

                            int tiresetonstockstatus = (int)Shared.TireSetStatus.OnStock;

                            if (OtherTireSetAction == 0)
                            {
                                // Customer has tireset
                                tiresetonstockstatus = (int)Shared.TireSetStatus.PlacedAtCustomer;
                            }
                            if (OtherTireSetAction == 1)
                            {
                                // Tirest should be picked up - create task
                                tiresetonstockstatus = (int)Shared.TireSetStatus.PlacedAtCustomer;

                                // Create pickup tireset (Will happen furtherdown in code when tireset is created)
                            }
                            if (OtherTireSetAction == 2)
                            {
                                // We already have the tireset
                                tiresetonstockstatus = (int)Shared.TireSetStatus.OnStock;

                                // TODO: Make code for selecting right container
                            }

                            // Check current tires on car
                            if (carinfo.CurrentTireset == 0)
                            {
                                // Winter tires on car
                                tireset1status = tiresetonstockstatus;
                                if (customer.LatitudePrimary == null | customer.LongitudePrimary == null)
                                {
                                    // HACK: Lorte work around, pga. Googlemaps er ude af drift 11/9-2013
                                    tireset1container = containerBLL.ReturnNearestContainerCargoRoomId(db, null, null);
                                }
                                else
                                {
                                    tireset1container = containerBLL.ReturnNearestContainerCargoRoomId(db, float.Parse(customer.LatitudePrimary.ToString()), float.Parse(customer.LongitudePrimary.ToString()));
                                }
                                
                                tireset1lockingbolt = carinfo.OtherTiresetLockingbolts;
                                tireset2status = (int)Shared.TireSetStatus.MountedOnCar;
                                tireset2container = null;
                                tireset2lockingbolt = carinfo.CurrentTiresetLockingbolts;
                            }
                            else
                            {
                                // Summer tires on car
                                tireset1status = (int)Shared.TireSetStatus.MountedOnCar;
                                tireset1container = null;
                                tireset1lockingbolt = carinfo.CurrentTiresetLockingbolts;
                                tireset2status = tiresetonstockstatus;
                                if (customer.LatitudePrimary == null | customer.LongitudePrimary == null)
                                {
                                    // HACK: Lorte work around, pga. Googlemaps er ude af drift 11/9-2013
                                    tireset2container = containerBLL.ReturnNearestContainerCargoRoomId(db, null, null);
                                }
                                else
                                {
                                    tireset2container = containerBLL.ReturnNearestContainerCargoRoomId(db, float.Parse(customer.LatitudePrimary.ToString()), float.Parse(customer.LongitudePrimary.ToString()));
                                }
                                tireset2lockingbolt = carinfo.OtherTiresetLockingbolts; 
                            }

                            tiresetBLL.UpdateTireSet(
                                                db,
                                                tireset1,
                                                car,
                                                (int)Shared.TireType.SummerTires,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                tireset1lockingbolt,
                                                false,
                                                false,
                                                false,
                                                false,
                                                null,
                                                null,
                                                tireset1status,
                                                null,
                                                tireset1container,
                                                true,
                                                false,
                                                null,
                                                SystemUserId,
                                                null,
                                                true
                                            );

                            tiresetBLL.UpdateTireSet(
                                                db,
                                                tireset2,
                                                car,
                                                (int)Shared.TireType.WinterTires,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                null,
                                                tireset2lockingbolt,
                                                false,
                                                false,
                                                false,
                                                false,
                                                null,
                                                null,
                                                tireset2status,
                                                null,
                                                tireset2container,
                                                true,
                                                false,
                                                null,
                                                SystemUserId,
                                                null,
                                                true
                                            );

                            // Check if tireset should be picked-up, if yes: create task
                            if (OtherTireSetAction == 1)
                            {
                                if (tireset1.TireSetStatusId != (int)Shared.TireSetStatus.MountedOnCar)
                                {
                                    // Create servicedrive task
                                    pickuptask = taskBLL.CreateTask(db,
                                                                null,
                                                                (int)Shared.TaskType.ServiceDrive,
                                                                (int)Shared.TaskDetailType.ServiceDrive_PickUpTire,
                                                                (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                                customer,
                                                                car,
                                                                tireset1,
                                                                carinfo.PickupAddress,
                                                                carinfo.PickupZipCode,
                                                                carinfo.PickupCity,
                                                                0,
                                                                carinfo.RemarksToPickupAddress,
                                                                carinfo.PickupAddress,
                                                                carinfo.PickupZipCode,
                                                                carinfo.PickupCity,
                                                                0,
                                                                carinfo.RemarksToPickupAddress,
                                                                "Ny kunde",
                                                                1,
                                                                SystemUserId,
                                                                true);
                                }
                                else
                                {
                                    // Create servicedrive task
                                    pickuptask = taskBLL.CreateTask(db,
                                                                null,
                                                                (int)Shared.TaskType.ServiceDrive,
                                                                (int)Shared.TaskDetailType.ServiceDrive_PickUpTire,
                                                                (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                                customer,
                                                                car,
                                                                tireset2,
                                                                carinfo.PickupAddress,
                                                                carinfo.PickupZipCode,
                                                                carinfo.PickupCity,
                                                                0,
                                                                carinfo.RemarksToPickupAddress,
                                                                carinfo.PickupAddress,
                                                                carinfo.PickupZipCode,
                                                                carinfo.PickupCity,
                                                                0,
                                                                carinfo.RemarksToPickupAddress,
                                                                "Ny kunde",
                                                                1,
                                                                SystemUserId,
                                                                true);
                                }   
                            }

                            // Create service drive task
                            if (tireset1.TireSetStatusId != (int)Shared.TireSetStatus.MountedOnCar)
                            {
                                servicetask = taskBLL.CreateTask(db,
                                                            null,
                                                            (int)Shared.TaskType.ServiceDrive,
                                                            (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                            (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                            customer,
                                                            car,
                                                            tireset1,
                                                            customer.Address,
                                                            customer.ZipCode,
                                                            customer.City,
                                                            0,
                                                            null,
                                                            customer.SecondaryAddress,
                                                            customer.SecondaryZipCode,
                                                            customer.SecondaryCity,
                                                            0,
                                                            null,
                                                            "Ny kunde",
                                                            1,
                                                            SystemUserId,
                                                            true);
                            }
                            else
                            {
                                servicetask = taskBLL.CreateTask(db,
                                                            null,
                                                            (int)Shared.TaskType.ServiceDrive,
                                                            (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                            (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                            customer,
                                                            car,
                                                            tireset2,
                                                            customer.Address,
                                                            customer.ZipCode,
                                                            customer.City,
                                                            0,
                                                            null,
                                                            customer.SecondaryAddress,
                                                            customer.SecondaryZipCode,
                                                            customer.SecondaryCity,
                                                            0,
                                                            null,
                                                            "Ny kunde",
                                                            1,
                                                            SystemUserId,
                                                            true);
                            }

                            // Check if dependency between tirepick and servicetask needs to be made
                            if (OtherTireSetAction == 1)
                            {
                                taskBLL.AddDependencyToTask(db, pickuptask, servicetask);
                            }

                            // Add subscription and car to list for invoicing after submitting to database
                            created_customersubscriptions.Add(customersubscription);
                            created_cars.Add(car);

                            // Update car status
                            car.CarStatusId = (int)Shared.CarStatus.AwaitsTireChangePlanning; 
                        }
                    }



                    // Log reference source on sale
                    CustomerSalesReferenceHistory reference = new CustomerSalesReferenceHistory();
                    customer.CustomerSalesReferenceHistories.Add(reference);
                    reference.ReferenceSource = referencesource;
                    reference.OrderTotal = 0; // Temporary set value - will be updated further down

                    db.AddCustomerSalesReferenceHistory(reference);

                    // Check if order is based on a quotation
                    if (Session["QuotationId"] != null)
                    {
                        Quotation quotation = db.GetQuotation(Convert.ToInt32(Session["QuotationId"]));

                        if (quotation == null)
                        {
                            // Nothing - was not found, but dont "Crash" the ordering process
                        }
                        else
                        {
                            quotation.ActivationCount += 1;
                            if (quotation.ActivationLimit == 1)
                            {
                                // Activate quotation
                                quotation.Activationdate = DateTime.Now.Date;
                                customer.Quotations_Customer.Add(quotation);
                            }
                            else
                            {
                                if (quotation.ActivationLimit == quotation.ActivationCount)
                                {
                                    // Activate quotation
                                    quotation.Activationdate = DateTime.Now.Date;
                                }
                            }
                            
                            //db.AddQuotation(quotation);
                        }
                    }

                    // Commit changes to database
                    db.SubmitChanges();

                    // Create debtor in E-conomic
                    ecoInterface.CreateDebtor(customer, db);

                    // Create invoice lines
                    foreach (CustomerSubscription newsubscription in created_customersubscriptions)
                    {
                        foreach (Car newcar in created_cars.Where(p => p.CustomerSubscriptionId == newsubscription.CustomerSubscriptionId))
                        {
                            // For Subscription and Car
                            EconomicInterface.EcoOrderLine orderline = new EconomicInterface.EcoOrderLine();
                            orderline.ProductNumber = 1; // Is not used - will be loaded from customersubscription
                            orderline.Description = "Abonnement"; // Is not used - will be loaded from customersubscription
                            orderline.Quantity = 1; // Is not used - will be loaded from customersubscription
                            orderline.UnitPrice = 1; // Is not used - will be loaded from customersubscription
                            orderline.CustomerSubscriptionId = newsubscription.CustomerSubscriptionId;

                            orderlines.Add(orderline);

                            // Check if car selected tirepick-up
                            foreach (CarData carinfo in cardata.Where(p => p.RegistrationNumber == newcar.RegistrationNumber))
                            {
                                if (carinfo.OtherTireset == 1)
                                {
                                    // Invoicing for tirepick up
                                    EconomicInterface.EcoOrderLine orderline_tirepickup = new EconomicInterface.EcoOrderLine();
                                    orderline_tirepickup.ProductNumber = 3; // TODO: Make more dynamic
                                    orderline_tirepickup.Description = "Afhentning af hjul for bil: " + carinfo.RegistrationNumber + " (" + carinfo.PickupAddress + ", " + carinfo.PickupZipCode + " " + carinfo.PickupCity + ")";
                                    orderline_tirepickup.Quantity = 1;
                                    orderline_tirepickup.UnitPrice = _tirepickupprice_beforevat; // TODO: Make more dynamic

                                    orderlines.Add(orderline_tirepickup);
                                }
                            }
                        }
                    }

                    // Create orderlines for none subscription products
                    foreach (OrderData customerorder in customerorders.Where(p => p.SubscriptionId == null))
                    {
                        // Invoicing for tirepick up
                        EconomicInterface.EcoOrderLine orderline_otherproduct = new EconomicInterface.EcoOrderLine();
                        orderline_otherproduct.ProductNumber = customerorder.ProductNumber;
                        orderline_otherproduct.Description = customerorder.Description;
                        orderline_otherproduct.Quantity = customerorder.Quantity;
                        orderline_otherproduct.UnitPrice = customerorder.UnitPrice; // TODO: Check if VAT if working correctly

                        orderlines.Add(orderline_otherproduct);
                    } 

                    // Create invoice in e-conomic
                    string invoiceid = ecoInterface.CreateInvoice(db, customer.CustomerId, orderlines, true);

                    // Prepare email
                    EmailNotificationServices emailService = new EmailNotificationServices();

                    try
                    {
                        // Create user
                        MembershipUser user = Membership.CreateUser(customer.Email, customer.Phone1.ToString(), customer.Email);

                        // Add user to customer role
                        Roles.AddUserToRole(user.UserName, "Kunde");

                        customer.UserId = new Guid(user.ProviderUserKey.ToString());

                        db.SubmitChanges();

                        // Send email to user with user information
                        emailService.Customer_UserInformation_SendCustomerEmail(customer.Email, customer.Name, user.UserName, customer.Phone1.ToString(), customer.CustomerId);
                    }
                    catch (Exception ex)
                    {
                        // Nothing, but error does not stop signup process for customer

                        // Send email to mobil hjulskift with error
                        string emailaddress = Convert.ToString(ConfigurationManager.AppSettings["EmailAddress"]);
                        bool test = Convert.ToBoolean(Convert.ToByte(ConfigurationManager.AppSettings["TestEnvironmentOn"]));
                        string message = String.Format("Systemet fejlede ved forsøg på at oprette kunde login<br><br>Email: {0}<br><br>Fejl: {1}", customer.Email, ex.Message);


                        Shared emailBLL = new Shared();
                        emailBLL.SendEmail(emailaddress, emailaddress, message, "Fejl ved oprettelse af brugerlogin", true, test, null, null, null);
                    }

                    // Send email with order confirmation to customer
                    string BookingLink = Convert.ToString(ConfigurationManager.AppSettings["BookingURL"]) + "?uid=" + customer.UserId.ToString();
                    emailService.Customer_OrderConfirmationAndInvoice_SendCustomerEmail(customer.CustomerId, customer.Email, customer.Name, invoiceid, ecoInterface.GetInvoice(Convert.ToInt32(invoiceid)), "Faktura" + invoiceid + ".pdf", Convert.ToString((int)Shared.PaymentGateWayActions.InitiatePayment), Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]), BookingLink);

                    // Send email to finance with order details
                    //emailService.SendFinanceInternalEmailNotification("Ordre bestilling - abonnement", "Kundenr: " + customerid + "<br>Faktura nr: " + invoiceid);

                    // Update reference sale
                    string amount = string.Format("{0:N}", ecoInterface.GetInvoiceRemainder(Convert.ToInt32(invoiceid), customer.CustomerId)).Replace(".", "").Replace(",", "");

                    reference.OrderTotal = Convert.ToDecimal(amount);
                    reference.InvoiceId = Convert.ToInt32(invoiceid);

                    // Update subscription if order was based on voucher and it was only onetime price
                    if (OneTimePrice)
                    {
                        // Update subscriptions so new price is used going forward
                        foreach (CustomerSubscription newsubscription in created_customersubscriptions)
                        {
                            OrderData corderdata = customerorders.SingleOrDefault(p => p.SubscriptionId == newsubscription.SubscriptionId);

                            if (corderdata != null)
	                        {
		                        newsubscription.Price = corderdata.UnitPrice;
	                        }
                        }
                    }

                    db.SubmitChanges();

                    // Reset session variables
                    Session["CustomerOrder"] = null;
                    Session["CarList"] = null;
                    Session["QuotationId"] = null;

                    if (paymentmethod == 1)
                    {
                        //// Payment with creditcard
                        //string acceptURL = Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]) + "?iid=" + invoiceid + "&cid=" + customer.CustomerId.ToString() + "&action=" + Convert.ToString((int)Shared.PaymentGateWayActions.PaymentCompleted);
                        //string declineURL = Convert.ToString(ConfigurationManager.AppSettings["DeclineURL"]) + "?iid=" + invoiceid + "&action=" + Convert.ToString((int)Shared.PaymentGateWayActions.PaymentFailed);

                        //NameValueCollection data = HelperFunctions.OnlinePayment(amount,
                        //                              invoiceid,
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopCurrency"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopMd5Key"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopId"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopOrderPrefix"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopPayType"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopCardType"]),
                        //                              Convert.ToString(ConfigurationManager.AppSettings["ShopLanguage"]),
                        //                              acceptURL,
                        //                              declineURL
                        //                             );

                        //string postbackForm = HttpHelper.SimplePreparePOSTForm(Convert.ToString(ConfigurationManager.AppSettings["ShopAuthURL"]), data);

                        //// Set session to indicate that redirection to payment gateway has been done
                        //Session["RedirectedToPaymentGateway"] = true;

                        //e.Result = postbackForm;
                        e.Result = string.Format("{0}?cid={1}&iid={2}&action={3}", Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]), customer.CustomerId, invoiceid, Convert.ToString((int)Shared.PaymentGateWayActions.InitiatePayment));
                        //Response.Redirect(RedirectPayment);
                    }
                    else
                    {
                        // Bank transfer - nothing happens, maybe a postback
                        e.Result = "Oprettelse blev gennemført";
                    }
                }
                else
                {
                    // Raise exception - no products selected
                    throw new ArgumentException("Ordre kan ikke gennemføres da ingen produkter er valgt - venligst prøv igen.");
                }

                // Close connection to database
                db.Dispose();
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function - not yet used
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void callbackStep5_Payment_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            try
            {

            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function that load vouche / quotation
        /// </summary>
        protected void callBackLoadVoucher_Callback(object sender, CallbackEventArgs e)
        {
            try
            { 
                // Validate voucher / quotation
                string[] param = e.Parameter.Split('-');

                if (param.Count() != 3)
                {
                    // Quotation is not valid
                    throw new ArgumentException("Indtastet rabat-/tilbudskode er ikke gyldig - venligst prøv igen.");
                }

                // Quotation is defined by: QuotationId-CreatedateYear-QuotationCode (ex. 1000-2013-100)
                int QuotationId = Convert.ToInt32(param[0]);
                int DateYear = Convert.ToInt32(param[1]);
                int QuotationCode = Convert.ToInt32(param[2]);

                // Initiate database
                TireServiceDB db = new TireServiceDB();

                // Get quotation
                Quotation quotation = db.GetQuotation(QuotationId, DateYear, QuotationCode);

                if (quotation == null)
                {
                    throw new ArgumentException("Indtastet rabat-/tilbudskode er ikke gyldig - venligst prøv igen.");
                }
                else
                {
                    // Validate if quotation is still active
                    if (quotation.Expiredate <= DateTime.Now)
                    {
                        throw new ArgumentException("Indtastet rabat-/tilbudskode er udløbet - venligst kontakt vores kundesupport.");
                    }
                    if (quotation.Activationdate != null)
                    {
                        throw new ArgumentException("Indtastet rabat-/tilbudskode er allerede brugt.");
                    }
                    if (quotation.ActivationLimit <= quotation.ActivationCount)
                    {
                        throw new ArgumentException("Indtastet rabat-/tilbudskode er udløbet - venligst kontakt vores kundesupport.");
                    }

                    // Get quotation details
                    List<QuotationDetail> quotationdetails = db.GetQuotationDetails(quotation.QuotationId);

                    if (quotationdetails == null)
                    {
                        throw new ArgumentException("Indtastet rabat-/tilbudskode indeholder ingen produkter - venligst kontakt vores kundesupport.");
                    }

                    // Load quotation details into order
                    List<OrderData> customerorders = new List<OrderData>();

                    bool SubscriptionIncluded = false;

                    foreach (QuotationDetail quotationdetail in quotationdetails)
                    {
                        // Create orderline
                        OrderData customerorder = new OrderData();
                        customerorder.SubscriptionId = quotationdetail.SubscriptionId;
                        customerorder.Description = quotationdetail.Description;
                        customerorder.ProductNumber = quotationdetail.ProductNumber;
                        customerorder.Quantity = quotationdetail.Quantity;
                        if (quotation.OneTimeDiscount & quotationdetail.SubscriptionId != null)
                        {
                            customerorder.UnitPrice = db.GetSubscriptionPrice(Convert.ToInt32(quotationdetail.SubscriptionId));
                        }
                        else
	                    {
                            customerorder.UnitPrice = quotationdetail.UnitPrice;
	                    }
                        customerorder.OneTimeUnitPrice = quotationdetail.UnitPrice;
                        customerorder.TotalPrice = (quotationdetail.Quantity * quotationdetail.UnitPrice);

                        // Check if quotation contains any subscriptions
                        if (quotationdetail.SubscriptionId != null)
                        {
                            SubscriptionIncluded = true;
                        }

                        customerorders.Add(customerorder);
                    }

                    // Update session with added orders
                    Session["CustomerOrder"] = customerorders;

                    // Store quotation in order process for later use
                    Session["QuotationId"] = Convert.ToInt32(quotation.QuotationId);

                    if (!SubscriptionIncluded)
                    {
                        // No subscriptions in quotation - skip other steps with customerinfo, carinfo
                        e.Result = "0";
                    }
                    else
	                {
                        e.Result = "1";
	                }
                }

            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Callback function that saves finalise payment of order that DO NOT contain subscriptions (Customer must also exist already)
        /// </summary>
        protected void callBackFinaliseOrderNoSubscription_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                // Get values from client
                int paymentmethod = Convert.ToInt32(e.Parameter);
                
                // Initiate database connection
                TireServiceDB db = new TireServiceDB();

                // Check if order is based on a quotation
                if (Session["QuotationId"] != null)
                {
                    Quotation quotation = db.GetQuotation(Convert.ToInt32(Session["QuotationId"]));

                    if (quotation == null)
                    {
                        // Raise error
                        throw new ArgumentException("Indtastet rabat-/tilbudskode ikke fundet.");
                    }
                    else
                    {
                        if (quotation.CustomerId == null)
                        {
                            // Raise error
                            throw new ArgumentException("Indtastet rabat-/tilbudskode ikke gyldig.");
                        }
                        else
                        {
                            // Get customer
                            Customer customer = db.GetCustomer(Convert.ToInt32(quotation.CustomerId));


                            if (Session["CustomerOrder"] != null)
                            {
                                // Activate quotation
                                quotation.Activationdate = DateTime.Now.Date;

                                // Get existing orders from session
                                List<OrderData>  customerorders = (List<OrderData>)Session["CustomerOrder"];

                                // Create orderlines for invoicing
                                List<EconomicInterface.EcoOrderLine> orderlines = new List<EconomicInterface.EcoOrderLine>();

                                // Initiate E-conomic interface
                                EconomicInterface ecoInterface = new EconomicInterface();

                                // Create orderlines for none subscription products
                                foreach (OrderData customerorder in customerorders.Where(p => p.SubscriptionId == null))
                                {
                                    // Invoicing
                                    EconomicInterface.EcoOrderLine orderline = new EconomicInterface.EcoOrderLine();
                                    orderline.ProductNumber = customerorder.ProductNumber;
                                    orderline.Description = customerorder.Description;
                                    orderline.Quantity = customerorder.Quantity;
                                    orderline.UnitPrice = customerorder.UnitPrice; // TODO: Check if VAT if working correctly

                                    orderlines.Add(orderline);
                                }

                                // Create invoice in e-conomic
                                string invoiceid = ecoInterface.CreateInvoice(db, customer.CustomerId, orderlines, true);

                                // Prepare email
                                EmailNotificationServices emailService = new EmailNotificationServices();

                                // Send email with order confirmation to customer
                                string BookingLink = Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]) + "?uid=" + customer.UserId.ToString();
                                emailService.Customer_OrderConfirmationAndInvoice_SendCustomerEmail(customer.CustomerId, customer.Email, customer.Name, invoiceid, ecoInterface.GetInvoice(Convert.ToInt32(invoiceid)), "Faktura" + invoiceid + ".pdf", Convert.ToString((int)Shared.PaymentGateWayActions.InitiatePayment), Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]), BookingLink);

                                // Send email to finance with order details
                                emailService.SendFinanceInternalEmailNotification("Ordre bestilling - andet køb", "Kundenr: " + customer.CustomerId.ToString() + "<br>Faktura nr: " + invoiceid);

                                // Update reference sale
                                string amount = string.Format("{0:N}", ecoInterface.GetInvoiceRemainder(Convert.ToInt32(invoiceid), customer.CustomerId)).Replace(".", "").Replace(",", "");

                                db.SubmitChanges();

                                if (paymentmethod == 1)
                                {
                                    //// Payment with creditcard
                                    //string acceptURL = Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]) + "?iid=" + invoiceid + "&cid=" + customer.CustomerId.ToString() + "&action=" + Convert.ToString((int)Shared.PaymentGateWayActions.PaymentCompleted);
                                    //string declineURL = Convert.ToString(ConfigurationManager.AppSettings["DeclineURL"]) + "?iid=" + invoiceid + "&action=" + Convert.ToString((int)Shared.PaymentGateWayActions.PaymentFailed);

                                    //NameValueCollection data = HelperFunctions.OnlinePayment(amount,
                                    //                              invoiceid,
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopCurrency"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopMd5Key"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopId"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopOrderPrefix"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopPayType"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopCardType"]),
                                    //                              Convert.ToString(ConfigurationManager.AppSettings["ShopLanguage"]),
                                    //                              acceptURL,
                                    //                              declineURL
                                    //                             );

                                    //string postbackForm = HttpHelper.SimplePreparePOSTForm(Convert.ToString(ConfigurationManager.AppSettings["ShopAuthURL"]), data);

                                    //// Set session to indicate that redirection to payment gateway has been done
                                    //Session["RedirectedToPaymentGateway"] = true;

                                    //e.Result = postbackForm;
                                    e.Result = string.Format("{0}?cid={1}&iid={2}&action={3}", Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]), customer.CustomerId, invoiceid, Convert.ToString((int)Shared.PaymentGateWayActions.InitiatePayment));
                                }
                                else
                                {
                                    // Bank transfer - nothing happens, maybe a postback
                                    e.Result = "Oprettelse blev gennemført";
                                }
                            }
                            else
                            {
                                throw new ArgumentException("Indtastet rabat-/tilbudskode indeholder ingen produkter - venligst kontakt vores kundesupport.");
                            }
                        }
                    }
                }
                else
                {
                    // Raise error
                    throw new ArgumentException("Indtastet rabat-/tilbudskode blev ikke fundet - venligst kontakt vores kundesupport.");
                }

            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }
    }

    /// <summary>
    /// Class for OrderData - used to store information in object and session variables during signup
    /// </summary>
    public class OrderData
    {
        private int? _subscriptionid;
        private int _productnumber;
        private string _description;
        private decimal _quantity;
        private decimal _unitprice;
        private decimal _onetimeunitprice;
        private decimal _totalprice;

        public int? SubscriptionId
        {
            get
            {
                return this._subscriptionid;
            }
            set
            {
                this._subscriptionid = value;
            }
        }

        public int ProductNumber
        {
            get
            {
                return this._productnumber;
            }
            set
            {
                this._productnumber = value;
            }
        }

        public string Description
        {
            get
            {
                return this._description;
            }
            set
            {
                this._description = value;
            }
        }

        public decimal Quantity
        {
            get
            {
                return this._quantity;
            }
            set
            {
                this._quantity = value;
            }
        }

        public decimal UnitPrice
        {
            get
            {
                return this._unitprice;
            }
            set
            {
                this._unitprice = value;
            }
        }

        public decimal OneTimeUnitPrice
        {
            get
            {
                return this._onetimeunitprice;
            }
            set
            {
                this._onetimeunitprice = value;
            }
        }

        public decimal TotalPrice
        {
            get
            {
                return this._totalprice;
            }
            set
            {
                this._totalprice = value;
            }
        }
    }

    public class CarData 
    {
        private int _carnumber;
        private int _subscriptionid;
        private string _registrationnumber;
        private int _carbrandid;
        private string _model;
        private string _enginesize;
        private int _fueltype;
        private int _year;
        private string _color;
        private int _currenttireset;
        private bool _currenttiresetlockingbolts;
        private int _othertireset;
        private bool _othertiresetlockingbolts;
        private string _pickupaddress;
        private string _pickupzipcode;
        private string _pickupcity;
        private string _remarkstopickupaddress;

        public int CarNumber
        {
            get
            {
                return this._carnumber;
            }
            set
            {
                this._carnumber = value;
            }
        }

        public int SubscriptionId
        {
            get
            {
                return this._subscriptionid;
            }
            set
            {
                this._subscriptionid = value;
            }
        }

        // 0: Registrationnumber
        public string RegistrationNumber
        {
            get
            {
                return this._registrationnumber;
            }
            set
            {
                this._registrationnumber = value;
            }
        }

        // 1: Car brand id
        public int CarBrandId
        {
            get
            {
                return this._carbrandid;
            }
            set
            {
                this._carbrandid = value;
            }
        }

        // 2: Car model
        public string Model
        {
            get
            {
                return this._model;
            }
            set
            {
                this._model = value;
            }
        }

        // 3: Enginesize
        public string EngineSize
        {
            get
            {
                return this._enginesize;
            }
            set
            {
                this._enginesize = value;
            }
        }

        // 4: Fueltype
        public int FuelType
        {
            get
            {
                return this._fueltype;
            }
            set
            {
                this._fueltype = value;
            }
        }

        // 5: Year
        // 4: Fueltype
        public int Year
        {
            get
            {
                return this._year;
            }
            set
            {
                this._year = value;
            }
        }

        // 6: Color
        public string Color
        {
            get
            {
                return this._color;
            }
            set
            {
                this._color = value;
            }
        }
        
        // 7: Currenttireset (0: Winter, 1: Summer)
        public int CurrentTireset
        {
            get
            {
                return this._currenttireset;
            }
            set
            {
                this._currenttireset = value;
            }
        }
        
        // 8: Locking bolts on current tireset (true/false)
        public bool CurrentTiresetLockingbolts
        {
            get
            {
                return this._currenttiresetlockingbolts;
            }
            set
            {
                this._currenttiresetlockingbolts = value;
            }
        }

        // 9: Othertireset (0: Get on first service, 1: Pick-up, 2: MBH has customer tires)
        public int OtherTireset
        {
            get
            {
                return this._othertireset;
            }
            set
            {
                this._othertireset = value;
            }
        }

        // 10: Locking bolts on other tireset (true/false)
        public bool OtherTiresetLockingbolts
        {
            get
            {
                return this._othertiresetlockingbolts;
            }
            set
            {
                this._othertiresetlockingbolts = value;
            }
        }

        // 11: Pickup address (optional)
        public string PickupAddress
        {
            get
            {
                return this._pickupaddress;
            }
            set
            {
                this._pickupaddress = value;
            }
        }

        // 12: Pickup zipcode (optional)
        public string PickupZipCode
        {
            get
            {
                return this._pickupzipcode;
            }
            set
            {
                this._pickupzipcode = value;
            }
        }

        // 13: Pickup city (optional)
        public string PickupCity
        {
            get
            {
                return this._pickupcity;
            }
            set
            {
                this._pickupcity = value;
            }
        }

        // 14: Remarks to pickup address (optional)
        public string RemarksToPickupAddress
        {
            get
            {
                return this._remarkstopickupaddress;
            }
            set
            {
                this._remarkstopickupaddress = value;
            }
        }









    }
}